<script setup>
import {ref, onMounted, computed} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {
  getStores, getFavoriteCountById,
  getReviewCountById,
  getAvgScoreById,
  getStoreLocationById,
  calculateDistance
} from "@/api/store";
import axios from "axios";
import {ElMessage} from "element-plus";
import {LocationInformation} from "@element-plus/icons-vue";
import userMarkerUrl from '@/assets/user-marker.png'
import storeMarkerUrl from '@/assets/store-marker.png'
import L from 'leaflet';

const route = useRoute()
const router = useRouter()
const categoryId = ref(route.params.id)
const stores = ref([])
const displayStores = ref([])
const sortOption = ref('favoriteDesc')  // 初始就对应“收藏最多”
const priceMin = ref('')
const priceMax = ref('')
const curLon = ref()
const curLat = ref()

const categoryMap = {
  '1': '美食',
  '2': '饮品',
  '3': '购物',
  '4': '娱乐',
  '5': '酒店',
  '6': '景点',
  '7': '运动',
  '8': '其他'
}

// 获取当前位置（IP定位）
const getLocationByIP = async () => {
  try {
    const res = await axios.get('https://ipapi.co/json/')
    curLon.value = res.data.longitude
    curLat.value = res.data.latitude
    console.info(curLon.value)
    console.info(curLat.value)
  } catch (err) {
    ElMessage.error('获取位置失败')
    console.error('获取位置失败:', err)
  }
}

const categoryKey = computed(() => categoryMap[categoryId.value])

const getStoresList = (category) => {
  getStores(category).then(res => {
    const list = res.data || []

    // 并发去拿每个 store 的三个统计值
    const statPromises = list.map(store => {
      return Promise.all([
        getFavoriteCountById(store.id),  // 收藏数
        getReviewCountById(store.id),    // 评论数
        getAvgScoreById(store.id)        // 平均分
      ]).then(([favRes, reviewRes, avgRes]) => {
        store.favoriteCount = favRes.data || 0
        store.reviewCount   = reviewRes.data || 0
        store.avgScore      = avgRes.data   || 0.0
      })
    })

    // Promise.all(statPromises).then(() => {
    //   stores.value = list
    //   sortList(sortOption)
    // })
    Promise.all(statPromises).then(() => {
      // 并发再取 location + 计算距离
      const distPromises = list.map(store => {
        // 先取店铺经纬度
        return getStoreLocationById(store.id).then(r1 => {
          const {longitude, latitude} = r1.data
          // 调用后端算距离
          return calculateDistance({lon1: curLon.value, lat1: curLat.value, lon2: longitude, lat2: latitude})
              .then(r2 => {
                store.distance = r2.data   // 单位 km，一位小数
                store.latitude  = latitude
                store.longitude = longitude
              })
        })
      })

      Promise.all(distPromises).then(() => {
        stores.value = list
        sortList(sortOption)
        initMap()
      })
    })
  })
}

const sortList = (option) => {
  const arr = stores.value.filter(store => {
    const okMin = priceMin.value === '' || store.priceMin >= priceMin.value
    const okMax = priceMax.value === '' || store.priceMax <= priceMax.value
    const okSub = selectedSub.value === '全部' || store.subCategory === selectedSub.value
    return okMin && okMax && okSub
  })

  arr.sort((a, b) => {
    switch (option.value) {
      case 'favoriteDesc':
        return (b.favoriteCount || 0) - (a.favoriteCount || 0)
      case 'ratingDesc':
        return (b.avgScore || 0) - (a.avgScore || 0)
      case 'priceAsc':
        return (a.priceMin || 0) - (b.priceMin || 0)
      case 'priceDesc':
        return (b.priceMax || 0) - (a.priceMax || 0)
      case 'distanceAsc':   // 距离最近
        return (a.distance || Infinity) - (b.distance || Infinity)
      case 'distanceDesc':  // 距离最远
        return (b.distance || 0) - (a.distance || 0)
      default:
        return 0
    }
  })
  displayStores.value = arr
  console.info(priceMin.value)
  console.info(priceMax.value)
}

const handleCategoryChange = (sub) => {
  selectedSub.value = sub
  sortList(sortOption)
}

const handleSortChange = () => {
  sortList(sortOption)
}

const selectStores = () => {
  sortList(sortOption)
}

const resetFilters = () => {
  sortOption.value = 'favoriteDesc'
  priceMin.value = ''
  priceMax.value = ''
  sortList(sortOption)
}

const subCatMap = {
  '1': ['全部', '川菜', '粤菜', '湘菜', '火锅', '烧烤', '日料', '韩餐', '小吃快餐', '西餐', '甜品'],
  '2': ['全部', '咖啡', '奶茶', '果汁', '冰淇淋'],
  '3': ['全部', '百货商场', '超市便利', '服装鞋包', '化妆品', '数码家电', '母婴用品', '家具家居'],
  '4': ['全部', '电影院', 'KTV', '密室逃脱', '桌游', '电玩城', '剧本杀'],
  '5': ['全部', '经济型', '商务型', '豪华型', '民宿客栈', '青年旅舍', '度假村'],
  '6': ['全部', '公园', '博物馆', '古镇古村', '游乐园', '海滩', '山地景区', '动物园'],
  '7': ['全部', '健身房', '游泳馆', '篮球馆', '羽毛球馆', '网球馆', '瑜伽', '攀岩', '滑冰滑雪'],
  '8': ['全部', '宠物', '医疗健康', '教育培训', '生活服务']
}
const subCategories = ref(subCatMap[categoryId.value] || ['全部'])
const selectedSub = ref('全部')

const sortOptions = [
  { value: 'favoriteDesc', label: '收藏最多' },
  { value: 'ratingDesc',   label: '评分最高' },
  { value: 'priceAsc',     label: '价格从低到高' },
  { value: 'priceDesc',    label: '价格从高到低' },
  { value: 'distanceAsc',  label: '距离最近' },
  { value: 'distanceDesc', label: '距离最远' },
]

let map; // 全局变量

// 3.1 初始化地图
function initMap() {
  if (map) map.remove(); // 切换类别时重建

  // 以用户位置为中心，如果还没定位成功就用 [0,0]
  const center = curLat.value && curLon.value
      ? [curLat.value, curLon.value]
      : [0, 0];

  map = L.map('category-map', {
    center,
    zoom: 7,
    zoomControl: true
  });

  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; OpenStreetMap contributors'
  }).addTo(map);

  // 用户标记
  if (curLat.value && curLon.value) {
    L.marker(center, {
      icon: L.icon({
        iconUrl: userMarkerUrl,
        iconSize: [50, 50],
        iconAnchor: [25, 50]
      })
    }).bindPopup('您在这里').addTo(map);
  }

  // 商家标记
  displayStores.value.forEach(store => {
    if (store.latitude && store.longitude) {
      L.marker([store.latitude, store.longitude], {
        icon: L.icon({
          iconUrl: storeMarkerUrl,
          iconSize: [50, 50],
          iconAnchor: [25, 50]
        })
      })
          .bindPopup(`
            <div>
                <strong>${store.name}</strong><br/>${store.address || ''}<br/>
                <a href="/user/storeDetailsPage/${store.id}" target="_self">查看详情</a>
            </div>
          `)
          .addTo(map);
    }
  });
}

onMounted(() => {
  getLocationByIP().then(() => {
    getStoresList(categoryKey.value)
  })
})

const toStorePage = (id) => {
  router.push(`/user/storeDetailsPage/${id}`)
}

</script>

<template>
  <div class="category-page">
    <div class="container">
      <!-- 顶部标题 -->
      <header class="category-header">
        <!--      <h1 class="category-title">{{ categoryKey }} 店铺</h1>-->
        <h1 class="category-title">
          <span>{{ categoryKey }} 店铺</span>
        </h1>

      </header>

      <!-- 子类别导航 -->
      <nav class="subcategory-nav">
        <ul class="subcategory-list">
          <li
              v-for="sub in subCategories"
              :key="sub"
              :class="['subcategory-item', { active: sub === selectedSub }]"
              @click="handleCategoryChange(sub)"
          >
            {{ sub }}
          </li>
        </ul>
      </nav>

      <!-- 筛选区 -->
      <section class="filter-bar">
        <div class="filter-group">
          <label>排序：</label>
          <el-select
              v-model="sortOption"
              clearable
              placeholder="收藏最多"
              class="filter-select"
              @change="handleSortChange"

          >
            <el-option
                v-for="item in sortOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </div>
        <div class="filter-group">
          <label>价格：</label>
          <input type="number" v-model.number="priceMin" placeholder="最低" class="filter-input"/>
          <span class="filter-separator">-</span>
          <input type="number" v-model.number="priceMax" placeholder="最高" class="filter-input"/>
          <button class="filter-reset" @click="selectStores">查询</button>
        </div>
        <button class="filter-reset" @click="resetFilters">重置</button>
      </section>

      <!-- 地图展示 -->
      <section class="map-section">
        <div id="category-map" class="category-map"></div>
      </section>

      <!-- 店铺列表 -->
      <main class="store-list">
        <article
            v-for="store in displayStores"
            :key="store.id"
            class="store-card"
            @click="toStorePage(store.id)"
        >
          <img
              :src="store.coverImage || defaultCover"
              alt="店铺封面"
              class="store-card__image"
          />
          <div class="store-card__body">
            <h2 class="store-card__title">{{ store.name }}</h2>
            <div class="store-card__tags">
            <span
                v-for="tag in store.tags"
                :key="tag"
                class="store-card__tag"
            >
              {{ tag }}
            </span>
            </div>
            <p class="store-card__description">
              {{ store.description }}
            </p>
            <div class="store-card__stats">
              <span class="stat stat--rating">⭐ {{ store.avgScore?.toFixed(1) || '-' }}</span>
              <span class="stat stat--reviews">💬 {{ store.reviewCount || 0 }}</span>
              <span class="stat stat--favorites">❤️ {{ store.favoriteCount || 0 }}</span>
              <span class="stat stat--price">￥{{ store.priceMin }}-{{ store.priceMax }}/人</span>
              <span class="stat stat--distance">
                <el-icon><LocationInformation/></el-icon>
                {{ store.distance }} km
              </span>
            </div>
          </div>
        </article>
      </main>
    </div>
  </div>
</template>


<style scoped lang="scss">
.container {
  width: 80%;
  max-width: 1200px;
  margin: 0 auto;
}

.category-page {
  padding: 1.5rem;
  background-color: #f7f7f7;
  min-height: 100vh;
}

.category-header {
  margin-bottom: 1rem;
}

.category-title {
  text-align: center;
  margin: 2rem 0 1.5rem;
  position: relative;
}


.category-title::before,
.category-title::after {
  content: "";
  display: block;
  width: 100px;
  height: 4px;
  background: linear-gradient(90deg, #3b82f6, #06b6d4);
  border-radius: 2px;
  margin: 0.5rem auto;
}

.category-title::before {
  margin-bottom: 0.75rem;
}

.category-title::after {
  margin-top: 0.75rem;
}

.category-title span {
  position: relative;
  font-size: 3rem;
}
.category-title span::before {
  content: "★ ";
}
.category-title span::after {
  content: " ★";
}

.subcategory-nav {
  margin-bottom: 1rem;
}

/* 子类别列表：Flex 布局，自动换行，居中对齐 */
.subcategory-list {
  display: flex;
  flex-wrap: wrap;            /* 超出时换行 */
  justify-content: center;    /* 各行项目居中 */
  gap: 0.5rem;                /* 项目间距 */
  max-width: 80%;           /* 与筛选框相同宽度 */
  margin: 0 auto;             /* 水平居中 */
  padding: 0;                 /* 去掉默认 ul 内边距 */
  list-style: none;           /* 去掉默认圆点 */
}

/* 每个子类别项 */
.subcategory-item {
  flex: 0 0 auto;             /* 宽度随内容自适应，不拉伸 */
  padding: 0.375rem 0.75rem;   /* 内边距 */
  background: #fff;            /* 白色背景 */
  border: 1px solid #cbd5e1;   /* 淡灰边框 */
  border-radius: 100px;       /* 椭圆形圆角 */
  font-size: 0.875rem;         /* 字体大小 */
  color: #4b5563;              /* 文本颜色 */
  text-align: center;          /* 文本居中 */
  cursor: pointer;             /* 指针样式 */
  transition:
      background 0.2s,
      color 0.2s,
      border-color 0.2s;         /* 过渡动画 */
}

/* 子类别项 悬停 状态 */
.subcategory-item:hover {
  background: #f3f4f6;         /* 浅灰背景 */
  border-color: #94a3b8;       /* 深一点的边框 */
}

/* 子类别项 选中(active) 状态 */
.subcategory-item.active {
  background: #3b82f6;         /* 主色调背景 */
  border-color: #2563eb;       /* 深主色边框 */
  color: #fff;                 /* 白色文字 */
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1.5rem;
  align-items: center;
  background: #fff;
  padding: 1rem 1.5rem;
  border-radius: 0.75rem;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.filter-select {
  width: 160px;
  background: linear-gradient(to right, #f9fafb, #f1f5f9);
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  padding: 0.2rem;
  transition: border-color 0.3s, box-shadow 0.3s;
}
.filter-select .el-select__caret-wrapper {
  color: #6b7280;
}
.filter-select:hover {
  border-color: #94a3b8;
}
.filter-select.is-focus {
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
}
.filter-select .el-select-dropdown__item:hover {
  background-color: #e0f2fe !important;
  color: #1e40af !important;
}
.filter-select .el-select-dropdown__item.selected {
  background-color: #bfdbfe !important;
  color: #1e3a8a !important;
}

.filter-input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
  background-color: #fff;
}

.filter-input {
  padding: 0.5rem;
  border: 1px solid #ddd;
  border-radius: 0.375rem;
  background: #f9f9f9;
}
.filter-reset {
  margin-left: auto;
  background: #3b82f6;
  color: #fff;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
  cursor: pointer;
  transition: background .2s;
}
.filter-reset:hover {
  background: #2563eb;
}

@media (max-width: 640px) {
  .filter-bar {
    padding: 0.75rem 1rem;
  }
  .container {
    width: 95%;
  }
}

.filter-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.filter-separator {
  color: #888;
}

.store-list {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.store-card {
  display: flex;
  background: #fff;
  border-radius: 0.5rem;
  overflow: hidden;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
  transition: box-shadow .2s;
}
.store-card:hover {
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.store-card__image {
  flex-shrink: 0;
  width: 300px;
  height: 180px;
  object-fit: cover;
  border-radius: 1rem;
  margin-top: 10px;
  margin-left: 10px;
  margin-bottom: 10px;
}
.store-card__body {
  flex: 1;
  padding: 1rem;
  display: flex;
  flex-direction: column;
}
.store-card__title {
  margin: 0;
  font-size: 1.25rem;
  color: #222;
}
.store-card__tags {
  margin: 0.5rem 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.store-card__tag {
  background: #e0f2fe;
  color: #0284c7;
  font-size: 0.75rem;
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
}
.store-card__description {
  flex: 1;
  margin: 0.5rem 0;
  color: #555;
  font-size: 0.875rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.store-card__stats {
  display: flex;
  gap: 1rem;
  font-size: 0.875rem;
  color: #666;
}
.stat {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.stat--rating { color: #f59e0b; }
.stat--favorites { color: #ef4444; margin-left: auto; }
@media (max-width: 640px) {
  .store-card { flex-direction: column; }
  .store-card__image {
    width: 100%;
    height: 160px;
  }
  .filter-bar {
    flex-direction: column;
    align-items: stretch;
  }
  .filter-reset {
    margin-left: 0;
  }
}

.stat--distance {
  color: #909399;
  margin-left: 0.5rem;
  font-size: 0.875rem;
}

.map-section {
  width: 100%;
  height: 40vh;       /* 可调整高度 */
  margin: 1.5rem 0;
  border-radius: 0.5rem;
  overflow: hidden;
}
.category-map {
  width: 100%;
  height: 100%;
}


</style>